using System;

namespace GraphSpace
{
	class MainClass
	{
		public static int Main (string[] args)
		{
			// $file
			// -s $ - startknoten
			// -t $- zielknoten
			// -z - zielgerichtet
			// -b - bi
			// -h - binheap
			// -d - dail
			
						
			int startknoten = System.Convert.ToInt32 (args[2]);
			int zielknoten = System.Convert.ToInt32 (args[4]);
			Knoten[] Pfad;
			
			bool bidirect = false, dial = false, goal = false;
				
			#region die Optionen einlesen und entsprechende Flags setzen
			for (int i = 5; i < args.Length; i++)
			{
				switch (args[i])
				{
				case "-z":
					{
						goal = true;
						break;
					}
				case "-b":
					{
						bidirect = true;
						break;
					}
				case "-h":
					{
						//binheap = true;
						break;
					}
				case "-d":
					{
						dial = true;
						break;
					}
				default:
					{
						Console.WriteLine ("Falscher Parameter!");
						break;
					}
				}
				;
			}
			#endregion
						
			if(bidirect)			// Bidirektionale Suche
			{
				// Graphen einlesen
				Graph<BiDijkstraKnoten, Kante> G = new Graph<BiDijkstraKnoten, Kante> ();
				G.ladeEuklidGraphBi(args[0]);
				// zweite Instanz des Graphen laden
				Graph<BiDijkstraKnoten, Kante> G2 = new Graph<BiDijkstraKnoten, Kante> ();
				G2.ladeEuklidGraphBi(args[0]);
			
					if(dial)		// zweimal Dials Implemtierung (Bidirektional)
					{
						// TODO
						BiSearch<BiDial<BiDijkstraKnoten>, BiDial<BiDijkstraKnoten>> Search = new BiSearch<BiDial<BiDijkstraKnoten>, BiDial<BiDijkstraKnoten>>(G.bestimmeMaxKantengewicht());
						Search.DoSearch(G, G2, startknoten, zielknoten, out Pfad, goal, goal); 
					}
					else 			// zwei einfache Binärheaps (Bidirektional)
					{
						// TODO
						BiSearch<BinaryHeap<BiDijkstraKnoten>, BinaryHeap<BiDijkstraKnoten>> Search = new BiSearch<BinaryHeap<BiDijkstraKnoten>, BinaryHeap<BiDijkstraKnoten>>();
						Search.DoSearch(G, G2, startknoten, zielknoten, out Pfad, goal, goal); 	
					}
			}
			else  					// Suche in einer Richtung
			{
				// Graphen einlesen
				Graph<DijkstraKnoten, Kante> G = new Graph<DijkstraKnoten, Kante> ();
				G.ladeEuklidGraph (args[0]);
								
					if(dial)		// Dials Implemtierung (n. Bidirektional)
					{
						// TODO
						uniSearch<Dial<DijkstraKnoten>> Search = new uniSearch<Dial<DijkstraKnoten>>(G.bestimmeMaxKantengewicht());
						Search.DoSearch(G, G.V[startknoten], G.V[zielknoten], out Pfad, goal);
					}
					else 			// einfacher Binärheap (n. Bidirektional)
					{
						// TODO
						uniSearch<BinaryHeap<DijkstraKnoten>> Search = new uniSearch<BinaryHeap<DijkstraKnoten>>();
						Search.DoSearch(G, G.V[startknoten], G.V[zielknoten], out Pfad, goal);
					}
				
			}
			
			Console.WriteLine("Länge des Pfades : "+Pfad.Length);
			foreach(Knoten v in Pfad)
				Console.WriteLine("\t"+v.Id);
			
			Graph<DijkstraKnoten, Kante> GTest = new Graph<DijkstraKnoten, Kante>();
			GTest.ladeEuklidGraph(args[0]);
			Console.WriteLine("n = "+GTest.V.Count+" m = "+GTest.M);
			
			Graph<BiDijkstraKnoten, Kante> GTestBi = new Graph<BiDijkstraKnoten, Kante>();
			GTestBi.ladeEuklidGraphBi(args[0]);
			Console.WriteLine("n = "+GTestBi.V.Count+" m = "+GTestBi.M);
			Console.WriteLine(GTestBi.E[0][0].Gewicht);
			
			/*
			foreach(Knoten v in G.V)
				Console.WriteLine(v.Id);
			
			Graph<DijkstraKnoten, Kante> G = new Graph<DijkstraKnoten, Kante>();
			G.ladeEuklidGraph("TestEuklidG.txt");
			
			*/
          // Graph<Knoten, Kante> G = Graphgenerator<Knoten,Kante>.generiere_Eulerkreis(10, 100);
		

            //Graph<DijkstraKnoten, Kante> G = new Graph<DijkstraKnoten, Kante> ();
            //G.ladeGraph ("testG2.txt");
            //foreach(Knoten v in G.V)
            //    Console.WriteLine(v.Id);
            //Graph<DijkstraKnoten, Kante> G2 = new Graph<DijkstraKnoten, Kante>();
            //G2.ladeGraph("myGraph.txt");

			/*
            Graph<BiDijkstraKnoten, Kante> G = new Graph<BiDijkstraKnoten, Kante>();
            G.ladeGraph("myGraph.txt");
            Graph<BiDijkstraKnoten, Kante> G2 = new Graph<BiDijkstraKnoten, Kante>();
            G2.ladeGraph("myGraph.txt");
			
			//Console.WriteLine ("G.N = " + G.V.Count + " \tG.M = " + G.M);

            BiSearch<BinaryHeap<BiDijkstraKnoten>, BinaryHeap<BiDijkstraKnoten>> Search3 = new BiSearch<BinaryHeap<BiDijkstraKnoten>, BinaryHeap<BiDijkstraKnoten>>();
            Knoten[] Pfad3;
            double res3 = Search3.DoSearch(G, G2, 0, 4, out Pfad3, false, false);

			
            //uniSearch<Dial<DijkstraKnoten>> Search = new uniSearch<Dial<DijkstraKnoten>> (10);
            //Knoten[] Pfad;
            //double res = Search.DoSearch (G, G.V[0], G.V[G.V.Count - 1], out Pfad, true);
            //uniSearch<BinaryHeap<DijkstraKnoten>> Search2 = new uniSearch<BinaryHeap<DijkstraKnoten>>();
            //Knoten[] Pfad2;
            //double res2 = Search2.DoSearch(G2, G2.V[0], G2.V[G.V.Count-1], out Pfad2, true);
            //for (int i = 0; i < Pfad.Length; i++)
            //{
            //    Console.WriteLine(Pfad[i].Id);
            //}
            //Console.WriteLine(res);
            //for (int i = 0; i < Pfad2.Length; i++)
            //{
            //    Console.WriteLine(Pfad2[i].Id);
            //}
            //Console.WriteLine(res2);
            //Console.ReadLine();
            */
			return 0;
		}
	}
}
